package com.tomatozq163.security.access;

import org.springframework.expression.EvaluationContext;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;

/**
 * 直接实现该类默认的用户密码验证会失效
 */
@Component("myAccessDecisionManager")
public class MyAccessDecisionManager implements AccessDecisionManager {
    private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();

    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        System.out.println(authentication);
        FilterInvocation fi = (FilterInvocation)object;
        String path = fi.getRequestUrl();

        System.out.println(path);
        System.out.println(configAttributes);

        // 这里将/login也放进来处理了

        //AuthenticatedVoter 针对antMatchers.permitAll处理
        for (ConfigAttribute attr : configAttributes) {
            if("permitAll".equals(attr.toString())){
                return;
            }
        }

        //WebExpressionVoter 针对注解处理
//        EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, fi);
//        ctx = weca.postProcess(ctx, fi);
//        return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ? 1 : -1;

        // 下面这种不能匹配/hello?name=XXX这种
//      AntPathMatcher matcher = new AntPathMatcher();
        //以下这种可以匹配
        AntPathRequestMatcher matcher =new AntPathRequestMatcher("/hello");

        if(matcher.matches(fi.getRequest())){
            return;
        }

        //AuthenticatedVoter 针对antMatchers.permitAll处理
        if(authentication!=null && AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass())){
            throw new AccessDeniedException("anonymous access denied!");
        }
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
